/****************************************************************************
 * Elisa 1.0                                                                *
 *--------------------------------------------------------------------------*
 * Author: Laurent Granvilliers, Vincent Sorin                              *
 * Copyright (c) 2004 Laboratoire d'Informatique de Nantes Atlantique       *
 *--------------------------------------------------------------------------*
 * Elisa is distributed WITHOUT ANY WARRANTY. Read the associated           *
 * COPYRIGHT file for more details.                                         *
 *--------------------------------------------------------------------------*
 * elisa_int_var.cpp                                                        *
 ****************************************************************************/

#include "elisa_int_var.h"
USING_ELISA

//--------------------------------------------------------------------------
// class IntVarImplementation
//--------------------------------------------------------------------------

void IntVarImplementation::setDomain(const Interval & I)
{
	RealVarImpl::setDomain(I.toInt());
}

void IntVarImplementation::setInterDomain(const Interval & I)
{
	RealVarImpl::setInterDomain(I.toInt());
}

void IntVarImplementation::setQuietDomain(const Interval & I)
{
	RealVarImpl::setQuietDomain(I.toInt());
}

void IntVarImplementation::split() const
{
	// Split of domain in I and J
	//Interval I, J;
	//VariableImpl::const_domain<Interval>().splitToInt(I, J);
	Interval::Pair r;
	r = VariableImpl::const_domain<Interval>().split();
	VariableImpl::splitBox<Interval>(r.first, r.second);
}

void IntVarImplementation::toPoint(Box *b) const
{
	Interval I = this->domain(b);
	Interval::Bound m = I.midInt();
	VariableImpl::setDomain<Interval>(Interval(m, m), b);
}

void IntVarImplementation::updateSymbolicDomain() const
{
	int lowerBound = toInt(this->domain().inf());
	int upperBound = toInt(this->domain().sup());

	IntSet & dom = (static_cast<IntVar *>(m_symbolicRep))->domain();
	dom.clear();
	for (int i = lowerBound; i <= upperBound; ++i) {
		dom.insert(i);
	}
}

//--------------------------------------------------------------------------
// class IntVar
//--------------------------------------------------------------------------

Variable *IntVar::copy(SearchTree *searchTree) const
{
	IntVar *v = new IntVar(this->const_domain(), this->m_name);
	v->buildImplementation(searchTree);
	return v;
}

void IntVar::buildImplementation(SearchTree *searchTree)
{
	int lowerBound = 1;
	int upperBound = -1;

	//std::set<int,ltint>::iterator it;
	std::set<int, ltint>::const_iterator it;
	it = this->domain().begin();
	if (it != this->domain().end()) {
		lowerBound = *it;
		upperBound = *it;
	}

	for (; it != this->domain().end(); ++it) {
		if (*it < lowerBound) {
			lowerBound = *it;
		}
		if (*it > upperBound) {
			upperBound = *it;
		}
	}

	m_implementation = VarImplPtr(new IntVarImplementation(this, searchTree, Interval(lowerBound, upperBound)));
}

